import copy
import sqlite3
from datetime import datetime, timedelta

import hyperlpr3 as lpr3
from fastapi import HTTPException

# 初始化 HyperLPR3-车牌识别框架
catcher = lpr3.LicensePlateCatcher()


# 从图像中识别获取车牌号
def recognize_plate(image):
    # 直接传入 OpenCV 图像（numpy.ndarray 类型）
    results = catcher(image)
    if results:
        return results[0][0]  # 返回识别到的第一个车牌号
    return None


# 当前未离开停车场的车辆
def get_active_plates():
    conn = sqlite3.connect('./license_plates.db')
    conn.row_factory = sqlite3.Row  # 返回字典格式
    c = conn.cursor()
    c.execute("SELECT * FROM current_plates")
    a = c.fetchall()
    c.execute("SELECT * FROM abnormal_plates")
    b = c.fetchall()
    conn.close()
    return [dict(row) for row in a+b]


def get_unactive_plates():
    conn = sqlite3.connect('./license_plates.db')
    conn.row_factory = sqlite3.Row  # 返回字典格式
    c = conn.cursor()
    c.execute("SELECT * FROM abnormal_plates")  # 查找退出时间为 NULL 的记录
    rows = c.fetchall()
    conn.close()
    return [dict(row) for row in rows]

# 获取指定时间范围内的进出车辆统计和费用信息
def get_time_range_info_plates(start_time: str, end_time: str):

    try:
        # 将字符串转换为 datetime 对象
        start_time = datetime.strptime(start_time, '%Y-%m-%d')
        end_time = datetime.strptime(end_time, '%Y-%m-%d')
        print(end_time)
        end_time = end_time + timedelta(hours=24)
        print(end_time)
    except ValueError:
        raise HTTPException(status_code=400, detail="Invalid date format. Please use YYYY-MM-DD.")

    conn = sqlite3.connect('./license_plates.db')
    conn.row_factory = sqlite3.Row  # 返回字典格式
    res = {
        "data": [],
        "cost_sum": 0
    }

    c = conn.cursor()
    # 合并查询进入和退出的记录
    c.execute(
        """
        SELECT * FROM plates 
        WHERE (enter_time >= ? AND enter_time <= ?) 
           OR (exit_time >= ? AND exit_time <= ?)
        """,
        (start_time.strftime('%Y-%m-%d %H:%M:%S'), end_time.strftime('%Y-%m-%d %H:%M:%S'),
         start_time.strftime('%Y-%m-%d %H:%M:%S'), end_time.strftime('%Y-%m-%d %H:%M:%S'))
    )

    # 获取所有符合条件的记录
    rows = c.fetchall()

    # 关闭数据库连接
    conn.close()
    res['data'] = [dict(row) for row in rows]

    def handle_data():
        data = copy.deepcopy(res)
        cost_num = 0

        for i in range(len(res['data'])):
            myobj = res['data'][i]
            enter_time = datetime.strptime(myobj["enter_time"], "%Y-%m-%d %H:%M:%S")
            if myobj["exit_time"] is None:
                exit_time_dt = datetime.now()
            else:
                exit_time_dt = datetime.strptime(myobj["exit_time"], "%Y-%m-%d %H:%M:%S")

            parking_duration = exit_time_dt - enter_time

            cost = calculate_parking_fee(parking_duration.total_seconds())
            cost_num += float(cost)

            data['data'][i]["parking_duration"] = parking_duration
            data['data'][i]["cost"] = calculate_parking_fee(parking_duration.total_seconds())

        data['cost_sum'] = cost_num

        return data

    return handle_data()


# 计费函数
def calculate_parking_fee(seconds):

    conn = sqlite3.connect('./license_plates.db')
    conn.row_factory = sqlite3.Row  # 返回字典格式
    c = conn.cursor()

    # 查询最新的费用设置
    c.execute('''
               SELECT * FROM fee_settings
               ORDER BY id DESC
               LIMIT 1
           ''')

    row = c.fetchone()
    conn.close()

    if row:
        fee_settings = dict(row)

    print(fee_settings)
    hours = seconds / 3600
    if hours <= 1:
        return fee_settings['fee_within_1_hour']
    elif hours <= 24:
        # 超过1小时部分按半小时计费
        extra_hours = hours - 1
        half_hours = int(extra_hours * 2)
        fee = fee_settings['fee_within_1_hour'] + half_hours * fee_settings['fee_after_1_hour']
        return min(fee, 50)  # 24小时内最高50元
    else:
        # 超过24小时，按天计算
        days = int(hours // 24)
        remaining_hours = hours % 24
        # 每天最高50元
        fee = days * fee_settings['fee_within_24_hours']
        # 剩余时间按正常计费
        if remaining_hours <= 1:
            fee += fee_settings['fee_within_1_hour']
        else:
            extra_hours = remaining_hours - 1
            half_hours = int(extra_hours * 2)
            fee += fee_settings['fee_within_1_hour'] + half_hours * fee_settings['fee_after_1_hour']
            fee = min(fee, (days + 1) * fee_settings['fee_within_24_hours'])  # 防止超过每日上限
        return fee
